# define STORE    sd
# define LOAD     ld
# define REGBYTES 8
#define MSTATUS_FS_INIT  (1 << 13)
#define MSTATUS_MIE		 (1 << 3)
#define MSTATUS_MPP		 (3 << 11)
	

.section .text
.global  _start

_start:

addi x1, zero, 0
addi x2, zero, 0
addi x3, zero, 0
addi x4, zero, 0
addi x5, zero, 0
addi x6, zero, 0
addi x7, zero, 0
addi x8, zero, 0
addi x9, zero, 0
addi x10, zero, 0
addi x11, zero, 0
addi x12, zero, 0
addi x13, zero, 0
addi x14, zero, 0
addi x15, zero, 0
addi x16, zero, 0
addi x17, zero, 0
addi x18, zero, 0
addi x19, zero, 0
addi x20, zero, 0
addi x21, zero, 0
addi x22, zero, 0
addi x23, zero, 0
addi x24, zero, 0
addi x25, zero, 0
addi x26, zero, 0
addi x27, zero, 0
addi x28, zero, 0
addi x29, zero, 0
addi x30, zero, 0
addi x31, zero, 0

init_stack:
    /* set stack pointer */
    la	sp, _stack

#if defined (BOOT_FROM_ROM)
# copy data section
	la a0, _sidata
	la a1, _sdata
	la a2, _edata
	bge a1, a2, end_init_data

loop_init_data:
	LOAD a3, 0(a0)
	STORE a3, 0(a1)
	addi a0, a0, REGBYTES
	addi a1, a1, REGBYTES
	blt a1, a2, loop_init_data
end_init_data:
#endif

# zero-init bss section
	la a0, _sbss
	la a1, _ebss
	bge a0, a1, end_init_bss
loop_init_bss:
	STORE zero, 0(a0)
	addi a0, a0, REGBYTES
	blt a0, a1, loop_init_bss
	end_init_bss:

# zero-init stack section
	la a0, _stack_end
	la a1, __stack
	bge a0, a1, end_init_stack
loop_init_stack:
    /* init stack section */
 	STORE zero, 0(a0)
	addi a0, a0, REGBYTES
	blt a0, a1, loop_init_stack
end_init_stack:


	// Disable global interrupts
	li t0, MSTATUS_MIE
	csrc mstatus, t0
	// Disable all inerrupts
	csrw mie, zero
	// Enable M - mode
	li t0, MSTATUS_MPP
	csrs mstatus, t0
	// Enable floating-point.
	li t0, MSTATUS_FS_INIT
	csrs mstatus, t0
	// Clear all exception flags
	fscsr zero
	// Set address vector table and choice vectored mode
	la t0, __mtvec_clint_vector_table
	or t0, t0, 1
	csrw mtvec, t0

# sys init
call sys_init

call main
loop:
j loop

/* For when a trap is fired */
early_trap_entry:
#if 0
#if 0
	csrr a0, mepc
	csrr a1, mcause
	csrr a2, mtval
	csrr a3, mstatus
	csrr a4, time
	csrr a5, timeh
	jal trap_handle
#endif
    j early_trap_entry

#else
	/* System call and other traps */
	addi sp, sp, -REGBYTES*16
	STORE x1,  0*REGBYTES(sp)
	STORE x5,  1*REGBYTES(sp)
	STORE x6,  2*REGBYTES(sp)
	STORE x7,  3*REGBYTES(sp)
	STORE x10, 4*REGBYTES(sp)
	STORE x11, 5*REGBYTES(sp)
	STORE x12, 6*REGBYTES(sp)
	STORE x13, 7*REGBYTES(sp)
	STORE x14, 8*REGBYTES(sp)
	STORE x15, 9*REGBYTES(sp)
	STORE x16, 10*REGBYTES(sp)
	STORE x17, 11*REGBYTES(sp)
	STORE x28, 12*REGBYTES(sp)
	STORE x29, 13*REGBYTES(sp)
	STORE x30, 14*REGBYTES(sp)
	STORE x31, 15*REGBYTES(sp)

	csrr a0, mepc
	csrr a1, mcause
	csrr a2, mtval
	csrr a3, mstatus
	csrr a4, time
	csrr a5, timeh
	# mv   a4, sp
	jal trap_handle

	LOAD x1,  0*REGBYTES(sp)
	LOAD x5,  1*REGBYTES(sp)
	LOAD x6,  2*REGBYTES(sp)
	LOAD x7,  3*REGBYTES(sp)
	LOAD x10, 4*REGBYTES(sp)
	LOAD x11, 5*REGBYTES(sp)
	LOAD x12, 6*REGBYTES(sp)
	LOAD x13, 7*REGBYTES(sp)
	LOAD x14, 8*REGBYTES(sp)
	LOAD x15, 9*REGBYTES(sp)
	LOAD x16, 10*REGBYTES(sp)
	LOAD x17, 11*REGBYTES(sp)
	LOAD x28, 12*REGBYTES(sp)
	LOAD x29, 13*REGBYTES(sp)
	LOAD x30, 14*REGBYTES(sp)
	LOAD x31, 15*REGBYTES(sp)

	addi sp, sp, REGBYTES*16
#endif
	mret
